package com.mxl.service.channel.comm.impl;

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.mxl.common.MD5Util;
import com.mxl.common.helper.OrderStatus;
import com.mxl.common.helper.ServiceCode;
import com.mxl.dao.cashorder.CustomMerchantDao;
import com.mxl.dao.cashorder.impl.GatewayPayOrderDaoImpl;
import com.mxl.dao.cashorder.impl.GatewayReturnLogDaoImpl;
import com.mxl.dao.cashorder.impl.GatewayTransferCardOrderDaoImpl;
import com.mxl.dao.cashorder.impl.PurchaseOrderDaoImpl;
import com.mxl.dao.cashorder.model.CustomMerchant;
import com.mxl.dao.cashorder.model.GatewayPayOrder;
import com.mxl.dao.cashorder.model.GatewayReturnLog;
import com.mxl.dao.cashorder.model.GatewayTransferCardOrder;
import com.mxl.dao.cashorder.model.PurchaseOrder;
import com.mxl.service.channel.comm.CommStatusProcess;
import com.mxl.service.channel.comm.SettleChangeService;
import com.mxl.service.dto.ChargeResponse;
import com.mxl.service.notify.http.HttpSender;

/**
 * 目前直接更新状态999-- 成功的结算金额到商户表.//结算余额 是否零吞卡等情况 通知商户结果
 * 
 * @author xianglin.mo
 * 
 */
@Service("commStatusProcess")
public class CommStatusProcessImpl implements CommStatusProcess {
	private static final Logger logger = LoggerFactory
			.getLogger(CommStatusProcessImpl.class);
	private static final int USE_NO = 0;
	private static final int ISFROZEN = 1;
	private static final int ISNOTFROZEN = 0;
	private static final String UPDATE_PURCHASE_ORDER = "update purchaseorder s set s.state=? where s.id=?";
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
	@Resource(name = "gatewayTransferCardOrderDao")
	private GatewayTransferCardOrderDaoImpl gatewayTransferCardOrderDao;

	@Resource(name = "gatewayPayOrderDao")
	private GatewayPayOrderDaoImpl gatewayPayOrderDao;

	@Resource(name = "customMerchantDao")
	private CustomMerchantDao customMerchantDao;

	@Resource(name = "purchaseOrderDao")
	private PurchaseOrderDaoImpl purchaseOrderDao;

	@Resource(name = "gatewayReturnLogDao")
	private GatewayReturnLogDaoImpl gatewayReturnLogDao;

	@Resource(name = "httpSender")
	private HttpSender httpSender;

	@Resource(name = "settleChangeService")
	private SettleChangeService settleChangeService;

	public void dispatch(ChargeResponse response) {
		// 更新状态 gatewaypayorder 失败则需要更新purchaseorder 状态 结算金额到商户账户 然后再是 通知商户结果
		// 如果金额大于选择金额 失败
		logger.info("*****start Process ChargeResponse==" + response);
		GatewayPayOrder gorder = gatewayPayOrderDao.getPaymentOrder(response
				.getSeqNo());
		if (OrderStatus.SUCC.getValue() == gorder.getOrderStatus()
				|| OrderStatus.FAIL.getValue() == gorder.getOrderStatus()
				|| (OrderStatus.ING.getValue() == gorder.getOrderStatus() && OrderStatus.ING
						.getValue() == response.getStatus())) {
			logger.info("*********the GatewayPayOrder status is completion seqId:"
					+ gorder.getSeqId());
			return;
		}
		gorder.setErrorCode(response.getErrorCode());
		gorder.setRealAmount(response.getPayMoney());
		gorder.setLastUpdate(new Date());
		gorder.setOrderStatus(response.getStatus());
		if (OrderStatus.SUCC.getValue() == response.getStatus()) {
			// 结算金额 //查询商户配置。
			PurchaseOrder p = purchaseOrderDao.get(gorder.getPid());
			CustomMerchant c = customMerchantDao.findByMembercodeAndBosstype(
					gorder.getMemberCode(), p.getBossType());
			if (c != null
					&& ServiceCode.ISRETAINCARD.getKey() == c.getIsRetainCard()) {
				gorder.setAllowAmount(response.getPayMoney());
			} else {
				if (response.getPayMoney() >= gorder.getSelectAmount()
						&& response.getPayMoney() >= gorder.getOrderAmount()) {
					gorder.setAllowAmount(gorder.getSelectAmount());
					// 多余的钱 记录 吞卡表 这个时候余额是可用的 可通过余额卡支付。
					saveTransOrder(response, gorder, p, ISNOTFROZEN);
				} else {
					// 失败 吞卡记录吞卡表 状态冻结
					gorder.setOrderStatus(OrderStatus.FAIL.getValue());
					gorder.setAllowAmount(0L);
					saveTransOrder(response, gorder, p, ISFROZEN);
				}
			}
			// 更新gatewaypayorder
			gatewayPayOrderDao.update(gorder);
			settleChangeService.Processor(response.getChannelCode(), gorder);
			// 通知商户
			notifyMember(gorder, p, c.getMacKey());
		} else if (OrderStatus.FAIL.getValue() == response.getStatus()) {
			// 失败更新purchaseorder 状态
			PurchaseOrder p = purchaseOrderDao.get(gorder.getPid());
			CustomMerchant c = customMerchantDao.findByMembercodeAndBosstype(
					gorder.getMemberCode(), p.getBossType());
			gorder.setAllowAmount(0L);
			gatewayPayOrderDao.executeSqlUpdate(UPDATE_PURCHASE_ORDER, USE_NO,
					gorder.getPid());
			// 通知商户
			// 更新gatewaypayorder
			gatewayPayOrderDao.update(gorder);
			notifyMember(gorder, p, c.getMacKey());
		} else {
			// 更新gatewaypayorder
			gatewayPayOrderDao.update(gorder);
		}
	}

	private void notifyMember(GatewayPayOrder gorder, PurchaseOrder p,
			String key) {
		// 加签原串
		String date = sdf.format(new Date());
		String signO = MessageFormat
				.format("version=1.00member_code={0}order_time={1}order_id={2}order_amount={3}amount={4}seq_id ={5}card_no={6}card_pwd={7}ret_code={8}merchant_key={9}",
						gorder.getMemberCode(), date, gorder.getOrderId(),
						String.valueOf(gorder.getOrderAmount()),
						String.valueOf(gorder.getAllowAmount()),
						gorder.getSeqId(), p.getCardNo(), p.getCardPwd(),
						gorder.getErrorCode(), key);
		logger.debug("notify member berfor signO:" + signO);
		String md5Sign = new String(MD5Util.md5Hex(signO).toLowerCase());
		logger.debug("notify member  after md5Sign:" + md5Sign);
		String url = MessageFormat
				.format("version=1.00&member_code={0}&order_time={1}&order_id={2}&order_amount={3}&amount={4}&seq_id={5}&card_no={6}&card_pwd={7}&ret_code={8}&ret_msg={9}&sign_msg={10}",
						gorder.getMemberCode(), date, gorder.getOrderId(),
						String.valueOf(gorder.getOrderAmount()),
						String.valueOf(gorder.getAllowAmount()),
						gorder.getSeqId(), p.getCardNo(), p.getCardPwd(),
						gorder.getErrorCode(), "", md5Sign);
		GatewayReturnLog log = httpSender.postHttpData(new StringBuffer()
				.append(gorder.getNotifyUrl()).append("?").append(url)
				.toString());
		// 保存通知内容
		log.setErrorCode(gorder.getErrorCode());
		log.setMemberCode(gorder.getMemberCode());
		log.setOrderId(gorder.getSeqId());
		log.setOrderAmount(gorder.getOrderAmount());
		log.setPayResult(gorder.getOrderStatus() == 111 ? "S" : "F");
		gatewayReturnLogDao.save(log);
	}

	private void saveTransOrder(ChargeResponse response,
			GatewayPayOrder gorder, PurchaseOrder p, int isFrozen) {
		long amount = response.getPayMoney() - gorder.getSelectAmount();
		if (amount == 0) {
			return;
		} else if (amount < 0) {
			amount = response.getPayMoney();
		}
		GatewayTransferCardOrder torder = new GatewayTransferCardOrder();
		torder.setBalance(amount);
		torder.setBalanceAmount(amount);
		torder.setBossType(p.getBossType());
		torder.setCardNo(p.cardNo);
		torder.setCardPwd(p.cardPwd);
		torder.setCreationDate(new Date());
		torder.setIsFrozen(isFrozen);
		torder.setSeqId(gorder.getSeqId());
		gatewayTransferCardOrderDao.save(torder);
		// 结算余额给商户
	}
}
